Skip to content

fix(exports): support default-only module shape in ESM wrapper#72

Merged
chenjiahan merged 2 commits intorstackjs:mainfrom
BleedingDev:codex/bun-esm-wrapper-fallback
Feb 12, 2026
Merged

fix(exports): support default-only module shape in ESM wrapper#72
chenjiahan merged 2 commits intorstackjs:mainfrom
BleedingDev:codex/bun-esm-wrapper-fallback

Conversation

@BleedingDev
Copy link
Copy Markdown
Contributor

Summary

  • Replace createRequire(...).require('../dist/index.js') in exports/index.mjs with an ESM import.
  • Normalize the loaded module shape so wrapper exports work for:
    • named export (ReactRefreshRspackPlugin)
    • default export (default)
    • direct class export
  • Add a regression test that executes a copied wrapper against a default-only fixture module.

Why

In strict Bun mode, the ESM wrapper path can surface a default-only module shape where destructuring a named export is undefined.
This causes import DefaultExport, { ReactRefreshRspackPlugin } from '@rspack/plugin-react-refresh' to break depending on runtime/module interop shape.

This change keeps Node behavior intact while making the ESM wrapper resilient across runtime interop differences.

Validation

  • pnpm lint
  • pnpm test
  • bun --bun -e "import DefaultExport, { ReactRefreshRspackPlugin } from './exports/index.mjs'; const a = new DefaultExport(); const b = new ReactRefreshRspackPlugin(); console.log(a.options.reactRefreshLoader && b.options.reactRefreshLoader ? 'ok' : 'bad');"

All pass locally.

Maintainer Question

If you prefer a narrower compatibility target for wrapper export resolution, I can adjust the normalization logic accordingly.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @BleedingDev, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses an issue where the ESM wrapper for @rspack/plugin-react-refresh could fail in strict Bun mode when encountering a default-only module shape. The changes enhance the wrapper's resilience by normalizing module exports, ensuring consistent behavior across different runtime interop environments, while maintaining Node.js compatibility.

Highlights

  • ESM Wrapper Import Logic: Replaced createRequire with a direct ESM import for ../dist/index.js in exports/index.mjs.
  • Module Shape Normalization: Implemented logic to normalize the loaded module shape, ensuring the wrapper correctly handles named, default, and direct class exports.
  • Regression Test: Added a new regression test to validate the ESM wrapper's behavior with default-only fixture modules.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • exports/index.mjs
    • Replaced node:module's createRequire with a direct ESM import for ../dist/index.js.
    • Modified the ReactRefreshRspackPlugin assignment to include fallback logic for pluginModule?.ReactRefreshRspackPlugin, pluginModule?.default, and pluginModule itself to support various module export shapes.
  • test/exports-default-fallback.spec.mts
    • Added a new test file to verify that the ESM wrapper correctly handles modules that only provide a default export. The test dynamically creates a fixture module and a modified wrapper to simulate the scenario.
Activity
  • The author validated the changes locally by running pnpm lint, pnpm test, and a custom Bun script, all of which passed.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively resolves an ESM wrapper issue by transitioning from createRequire to a direct ESM import, complemented by robust fallback logic to accommodate various module export structures. This is a great improvement for compatibility with different JavaScript runtimes like Bun. The inclusion of a targeted regression test for the default-only export scenario is a strong addition that validates the fix. I have one suggestion regarding the new test file to enhance its readability.

Comment thread test/exports-default-fallback.spec.mts Outdated
Copy link
Copy Markdown
Member

@chenjiahan chenjiahan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@chenjiahan chenjiahan merged commit 385148a into rstackjs:main Feb 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants